class WSclient {
    constructor(url, opt) {
        if (url.constructor === Object) {
            opt = url;
            this.url = url = opt.url;
        }
        this.evtStack = {
            'close': [this.reconnection.bind(this)],
            'error': [],
            'message': [],
            'open': [(function () { this.reconnectionCount = 0; this.reconnectionTimer = null; }).bind(this)]
        };
        this.normalClose = false;//正常关闭标识
        this.EVENTS = Object.keys(this.evtStack);
        this.opt = Object.assign({
            reconnection: true,//断线重连
            reconnectionAttempts: Infinity,//重连次数
            reconnectionDelay: 1000,// 重连延时,1秒后尝试
            autoConnect: true,//创建自动连接
        }, opt && opt.constructor === Object ? opt : {});
        this.reconnectionCount = 0;//实际重试次数
        this.socket = this.reconnectionTimer = null;
        if (this.opt.autoConnect && url) this.connect(url);
    }
    send(...args){
        if(this.socket)this.socket.send(...args)
    }
    reconnection() {//重连
        if (!this.normalClose && this.opt.reconnection) {//非正常关闭&&需要重启
            if (this.opt.reconnectionAttempts > this.reconnectionCount) {//重试次数
                this.reconnectionCount++;
                clearInterval(this.reconnectionTimer);
                this.reconnectionTimer = setTimeout(this.connect.bind(this), this.opt.reconnectionDelay);
            }
        }
    }
    connect(url) {// 连接
        if (this.socket) {
            if (this.socket.readyState == this.socket.CLOSED) delete this.socket;//
            else this.socket.close();//关闭连接
        }
        this.url = url || this.url;
        this.socket = new WebSocket(this.url);
        this.normalClose = false;
        this.EVENTS.forEach(k => { this.evtStack[k].forEach(f => { this.socket.addEventListener(k, f) }) });//事件绑定
    }
    on(evt, _fun) {
        if (this.EVENTS.indexOf(evt) >= 0) {
            this.evtStack[evt].push(_fun);
            if (this.socket) this.socket.addEventListener(evt, _fun);
        }
    }
    close(...args) {
        this.normalClose = true;//正常关闭
        this.socket.close(...args);
    }
}